package com.niiwoo.civet.system.service.local;

import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.system.dao.entity.SysParam;
import com.niiwoo.civet.system.dao.mapper.SysParamMapperExt;
import com.niiwoo.civet.system.dto.ParamQueryDTO;
import com.niiwoo.civet.system.dto.common.SysConfParamDTO;
import com.niiwoo.civet.system.dto.request.QueryParamsRequestDTO;
import com.niiwoo.civet.system.enums.DelStatusEnum;
import com.niiwoo.civet.system.enums.SysParamTypeEnum;
import com.niiwoo.tripod.consumer.helper.Exceptions;
import com.niiwoo.tripod.provider.dto.response.PageResponseDTO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Service
public class SysParamLocalService {
    private final String SYS_CONF_MAP_ID = "sys_conf_map_id";
    private final String SYS_CONF_MAP_KEY = "sys_conf_map_key";
    @Autowired
    private SysParamMapperExt sysParamMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Transactional
    public int insertParam(SysParamTypeEnum paramType, String paramKey, String paramValue, String description, Long createManager) {
        int count = 0;
        count = sysParamMapper.selectCountByKey(paramKey);
        if (count > 0) {
            Exceptions.throwBizException("SYSPARAM10001", "paramKey is exist");
        }
        SysParam param = new SysParam();
        param.setParamType(paramType.getSign());
        param.setParamKey(paramKey);
        param.setParamValue(paramValue);
        param.setDescription(description);
        param.setDelFlag(DelStatusEnum.NORMAL.getValue());
        param.setCreateManager(createManager);
        sysParamMapper.insertSelective(param);

        String jsonStr= JSON.toJSONString(param);
        stringRedisTemplate.boundHashOps(SYS_CONF_MAP_ID).put(param.getId().toString(),jsonStr);
        stringRedisTemplate.boundHashOps(SYS_CONF_MAP_KEY).put(param.getParamKey(), jsonStr);

        return param.getId();
    }

    @Transactional
    public void deleteParam(Integer paramId, Long updateManager) {
        SysParam temp = sysParamMapper.selectByPrimaryKey(paramId);
        if (temp == null || DelStatusEnum.DEL.getValue().equals(temp.getDelFlag())) {
            return;
        }

        SysParam param = new SysParam();
        param.setId(paramId);
        param.setDelFlag(DelStatusEnum.DEL.getValue());
        param.setUpdateManager(updateManager);
        sysParamMapper.updateByPrimaryKeySelective(param);

        stringRedisTemplate.boundHashOps(SYS_CONF_MAP_ID).delete(paramId.toString());
        stringRedisTemplate.boundHashOps(SYS_CONF_MAP_KEY).delete(temp.getParamKey());
    }

    @Transactional
    public void updateParam(Integer paramId, String paramValue, String description, Long updateManager) {
        SysParam param = sysParamMapper.selectByPrimaryKey(paramId);
        if (param == null || DelStatusEnum.DEL.getValue().equals(param.getDelFlag())) {
            Exceptions.throwBizException("PARAM10001", "SysConfParam is not exist");
        }


        param.setParamValue(paramValue);
        param.setDescription(description);
        param.setUpdateManager(updateManager);
        sysParamMapper.updateByPrimaryKeySelective(param);

        stringRedisTemplate.boundHashOps(SYS_CONF_MAP_ID).put(param.getId().toString(), JSON.toJSONString(param));
        stringRedisTemplate.boundHashOps(SYS_CONF_MAP_KEY).put(param.getParamKey(), JSON.toJSONString(param));


    }

    public SysConfParamDTO queryParam(Integer paramId) {
        String jsonStr = (String) stringRedisTemplate.boundHashOps(SYS_CONF_MAP_ID).get(paramId.toString());

        if (!StringUtils.isEmpty(jsonStr)) {
            return JSON.parseObject(jsonStr, SysConfParamDTO.class);
        }
        SysParam param = sysParamMapper.selectByPrimaryKey(paramId);
        if (param == null || DelStatusEnum.DEL.getValue().equals(param.getDelFlag())) {
            return null;
        }
        stringRedisTemplate.boundHashOps(SYS_CONF_MAP_ID).put(paramId.toString(), JSON.toJSONString(param));
        return convertToSysConfParamDto(param);
    }

    public SysConfParamDTO queryParamByKey(String paramKey) {
        String jsonStr = (String) stringRedisTemplate.boundHashOps(SYS_CONF_MAP_KEY).get(paramKey);
        if (!StringUtils.isEmpty(jsonStr)) {
            return JSON.parseObject(jsonStr, SysConfParamDTO.class);
        }
        SysParam param = sysParamMapper.queryParamByKey(paramKey);
        if (param == null || DelStatusEnum.DEL.getValue().equals(param.getDelFlag())) {
            return null;
        }
        stringRedisTemplate.boundHashOps(SYS_CONF_MAP_KEY).put(paramKey, JSON.toJSONString(param));
        return convertToSysConfParamDto(param);


    }

    public PageResponseDTO<SysConfParamDTO> queryParams(QueryParamsRequestDTO queryParamsRequest) {

        ParamQueryDTO dto = new ParamQueryDTO();
        dto.setParamType(queryParamsRequest.getParamType() == null ? null : queryParamsRequest.getParamType().getSign());
        dto.setParamKey(queryParamsRequest.getParamKey() == null ? null : queryParamsRequest.getParamKey().toUpperCase());
        dto.setStart((queryParamsRequest.getPageNumber() - 1) * queryParamsRequest.getPageSize());
        dto.setEnd(queryParamsRequest.getPageSize());
        int totalCount = sysParamMapper.queryParamsCount(dto);
        List<SysParam> list = new ArrayList<SysParam>();
        if (totalCount > 0) {
            list.addAll(sysParamMapper.queryParams(dto));
        }
        PageResponseDTO<SysConfParamDTO> resp = new PageResponseDTO<SysConfParamDTO>();

        resp.measureTotalPage(totalCount, queryParamsRequest.getPageSize());
        List<SysConfParamDTO> dtoList = new ArrayList<SysConfParamDTO>();
        resp.setItems(dtoList);
        if (!CollectionUtils.isEmpty(list)) {
            for (SysParam param : list) {
                dtoList.add(convertToSysConfParamDto(param));
            }
        }
        return resp;
    }

    private SysConfParamDTO convertToSysConfParamDto(SysParam param) {
        if (param == null) {
            return null;
        }
        SysConfParamDTO paramDto = new SysConfParamDTO();
        BeanUtils.copyProperties(param, paramDto);
        return paramDto;
    }

}
